package org.erepublik.company.service;

import java.util.HashMap;
import java.util.List;

import org.erepublik.company.Company;
import org.erepublik.company.EAlliance;
import org.erepublik.company.Location;
import org.erepublik.company.charts.ChartDataSet;
import org.erepublik.company.charts.ECountryDataType;
import org.erepublik.company.searchCriteria.EFoodSearchCriteria;
import org.erepublik.company.searchCriteria.EHouseChartCriteria;
import org.erepublik.company.searchCriteria.EMovingDistance;
import org.erepublik.company.searchCriteria.EWeaponChartCriteria;
import org.erepublik.company.utils.HibernateUtil;
import org.erepublik.company.utils.Utils;
import org.hibernate.ObjectNotFoundException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * Metody posredniczace pomiedzy baza danych
 * 
 * @author Kacper Gorski 'Railman' railman85@gmail.com
 */
public class DatabaseProvider {

    public Object save(Object o) {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        Object object = session.save(o);
        tx.commit();
        return object;
    }

    public Company getCompanyById(int id) {

        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        Company company = null;
        try {
            company = (Company) session.load(Company.class, id);
            company.getId();
            tx.commit();
        } catch (ObjectNotFoundException e) {
            return null;
        }
        session.close();
        return company;
    }

    @SuppressWarnings("unchecked")
    public long[] getAvticeCompaniesId() {

        Session session = HibernateUtil.getSession();

        List<Company> idks = session.createQuery("from Company WHERE active='true'").list();
        long[] idTable = new long[idks.size()];
        for (int i = 0; i < idks.size(); i++) {
            idTable[i] = idks.get(i).getId();
        }

        session.close();
        return idTable;
    }

    public void deleteCompanyById(int id) {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        Company company = new Company();
        company.setId(id);
        session.delete(company);
        tx.commit();
        session.close();
    }

    public void updateObject(Object o) {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        session.update(o);
        tx.commit();
        session.close();
    }

    @SuppressWarnings("unchecked")
    public HashMap<Location, HashMap<String, ChartDataSet>> getDataSets(String resourceName) {

        Session session = HibernateUtil.getSession();
        HashMap<Location, HashMap<String, ChartDataSet>> chartData = new HashMap<Location, HashMap<String, ChartDataSet>>();

        List<ChartDataSet> charts = session.createQuery("from ChartDataSet where resourceName=?").setString(0, resourceName).list();
        for (ChartDataSet chartDataSet : charts) {
            Location country = Utils.getLocationFromString( chartDataSet.getCountry() );
            if (chartData.get(country) == null)
                chartData.put(country, new HashMap<String, ChartDataSet>());
            chartDataSet.getData().size(); // zeby doczytac lazy
            chartData.get(country).put(chartDataSet.getAttribute(), chartDataSet);
        }

        session.close();
        return chartData;
    }

    // program wypelnia baze danych pustymi obiektami ChartDataSet
    public static void main(String[] args) {
        database = new DatabaseProvider();
        createChartStartData(EFoodSearchCriteria.class, "food");
        createChartStartData(EMovingDistance.class, "ticket");
        createChartStartData(EHouseChartCriteria.class, "house");
        createChartStartData(EWeaponChartCriteria.class, "tank");
        createChartStartData(EWeaponChartCriteria.class, "rifle");
        createChartStartData(EWeaponChartCriteria.class, "helicopter");
        createChartStartData(EWeaponChartCriteria.class, "artillery");
        createChartStartData(ECountryDataType.class, "country");
    }

    @SuppressWarnings("unchecked")
    private static void createChartStartData(Class<? extends Enum> criteria, String productName) {

        ChartDataSet dataset = database.getDataSet(EAlliance.NEW_COUNTRIES.toString(), criteria.getEnumConstants()[0].toString(), productName);
        if (dataset != null) {
            System.out.println("data for " + productName + " already exists, skipping... ");
            return;
        }

        Location[] countries = Utils.getNewCountries();
        Enum[] foodType = criteria.getEnumConstants();

        for (Location country : countries) {
            for (Enum foodSearchCriteria : foodType) {
                insertEmptyChartToDatabase(productName, country.toString(), foodSearchCriteria.toString());
            }
        }


    }

    private static DatabaseProvider database = null;

    // jesli country == null, to chartsy sa z globalnych danych
    private static void insertEmptyChartToDatabase(String productType, String location, String name) {
        ChartDataSet dataSet = new ChartDataSet();
        dataSet.setCountry(location);
        dataSet.setResourceName(productType);
        dataSet.setAttribute(name);
        database.save(dataSet);
        System.out.println("saved to database " + productType + " " + name + " from location " + location + " ");
    }

    @SuppressWarnings("unchecked")
    public ChartDataSet getDataSet(String country, String string, String productName) {

        Session session = HibernateUtil.getSession();

        String countrySQL = "country is null";
        if (country != null)
            countrySQL = "country='" + country + "'";

        List<ChartDataSet> charts = session.createQuery(
                "from ChartDataSet where " + "resourceName='" + productName + "' AND " + "attribute='" + string + "' AND " + countrySQL)
                .list();
        if (charts.size() == 0) {
            session.close();
            return null;
        }
        ChartDataSet dataset = charts.get(0);

        session.close();
        return dataset;

    }

}
